package com.aganmall.service.impl;

import com.aganmall.common.Const;
import com.aganmall.common.ServerResponse;
import com.aganmall.common.TokenCache;
import com.aganmall.dao.UserMapper;
import com.aganmall.pojo.User;
import com.aganmall.service.IUserService;
import com.aganmall.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * Created by GJY on 17/5/13.
 */
@Service("iUserService") //用来将该service接口注入到controller
public class UserServiceImpl implements IUserService{

    @Autowired
    private UserMapper userMapper;

    @Override
    public ServerResponse<User> login(String username, String password) {
        int resultCount = userMapper.checkUsername(username); //1.校验用户名是否存在
        if (resultCount == 0){
            return ServerResponse.createByErrorMessage("用户名不存在");
        }

        //2.密码登录MD5:需要比较登录后的password
        String md5Password = MD5Util.MD5EncodeUtf8(password);

        User user = userMapper.selectLogin(username,md5Password);
        if (user == null){ //当逻辑执行到这里时,username已经存在,证明密码错误
            return ServerResponse.createByErrorMessage("密码错误");
        }

        user.setPassword(StringUtils.EMPTY);
        return ServerResponse.createBySuccess("登录成功",user);
    }

    public ServerResponse<String> register(User user){
        /*int resultCount = userMapper.checkUsername(user.getUsername());//1. 校验用户名是否已存在
        if (resultCount > 0){
            return ServerResponse.createByErrorMessage("用户名已存在");
        }*/
        //改写方法,重用checkValid中的方法,校验用户名是否已存在
        ServerResponse validResponse = this.checkValid(user.getUsername(),Const.USERNAME);
        if (!validResponse.isSuccess()){
            //当validResponse返回失败时,则说明用户名已存在;
            return validResponse;
        }

        /*resultCount = userMapper.checkEmail(user.getEmail());//2.校验Email是否已存在
        if (resultCount > 0){
            return ServerResponse.createByErrorMessage("email已存在");
        }*/
        //改写方法,重用checkValid中的方法,校验email是否已存在
        validResponse = this.checkValid(user.getEmail(),Const.EMAIL);
        if (!validResponse.isSuccess()){
            //当validResponse返回失败时,则说明email已存在
            return validResponse;
        }

        user.setRole(Const.Role.ROLE_CUSTOMER);
        //MD5加密
        user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));

        //resultCount表示插入的行数
        int resultCount = userMapper.insert(user);
        if (resultCount == 0){
            return ServerResponse.createByErrorMessage("注册失败");
        }

        return ServerResponse.createBySuccessMessages("注册成功");
    }

    //根据type来判断str,type如果是username则判断username是否合法;如果是email则判断email是否合法
    public ServerResponse<String> checkValid(String str, String type){
        if (org.apache.commons.lang3.StringUtils.isNotBlank(type)){
            //1.type不是空的话才开始校验
            if (Const.USERNAME.equals(type)){
                int resultCount = userMapper.checkUsername(str);
                if (resultCount > 0){
                    return ServerResponse.createByErrorMessage("用户名已存在");
                }
            }
            if (Const.EMAIL.equals(type)){
                int resultCount = userMapper.checkEmail(str);
                if (resultCount > 0){
                    return ServerResponse.createByErrorMessage("email已存在");
                }
            }
        }else {
            return ServerResponse.createByErrorMessage("参数错误");
        }
        //isSuccess表示返回成功,即可以创建,则用户名不存在;!isSuccess表示返回失败,即不可以创建,则用户名已经存在
        return ServerResponse.createBySuccessMessages("校验成功");
    }

    //忘记密码时:首先选择问题
    public ServerResponse selectQuestion(String username){
        //1.首先判断用户名是否存在(复用checkValid方法查询)
        ServerResponse validResponse = this.checkValid(username,Const.CURRENT_USER);
        if (validResponse.isSuccess()){
            //当validResponse返回成功时,用户名不存在
            return validResponse;
        }

        String question = userMapper.selectQuestionByUsername(username);
        if (StringUtils.isNotBlank(question)){
            return ServerResponse.createBySuccess(question);
        }
        return ServerResponse.createByErrorMessage("找回密码的问题是空的");
    }

    //忘记问题时:校验问题答案(需要set token)
    public ServerResponse<String> checkAnswer(String username, String question, String answer){
        int resultCount = userMapper.checkAnswer(username,question,answer);
        if (resultCount > 0){
            //1.说明问题及问题答案是这个用户的,并且是正确的
            String forgetToken = UUID.randomUUID().toString();
            //将token_username,forgetToken存在localcache中
            TokenCache.setKey(TokenCache.TOKEN_PREFIX+username, forgetToken); //设置local cache的key/value,username为key,token为value
            return ServerResponse.createBySuccess(forgetToken); //返回token(uuid定义的)
        }
        return ServerResponse.createByErrorMessage("问题的答案错误");
    }

    //忘记问题时:重设密码(需要get token)
    public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) {
        //1.校验forgetToken是否为空
        if (StringUtils.isBlank(forgetToken)) {
            return ServerResponse.createByErrorMessage("参数错误,token需要传递");
        }
        //2.校验username是否为存在(复用checkValid的方法),若username为空,则会得到"token_"
        ServerResponse validResponse = this.checkValid(username, Const.CURRENT_USER);
        if (validResponse.isSuccess()) {
            //用户不存在
            return ServerResponse.createByErrorMessage("用户不存在");
        }

        String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX + username);
        //对local cache中取到的token做校验:是否无效或过期
        if (StringUtils.isBlank(token)) {
            return ServerResponse.createByErrorMessage("token无效或过期");
        }

        //校验传入的forgetToken和local cache的toke是否equal(用StringUtils中的equal可以不管是否有null存在)
        if (StringUtils.equals(forgetToken, token)) {
            //3.校验通过,更新密码
            //设置密码时必须先转成MD5,不能直接使用明文密码
            String MD5Password = MD5Util.MD5EncodeUtf8(passwordNew);
            int rowCount = userMapper.updatePasswordByUsername(username, MD5Password);
            if (rowCount > 0) {
                return ServerResponse.createBySuccessMessages("修改密码成功");
            }
        }
        else {
            //forgetToken != token说明传参token错误
            return ServerResponse.createByErrorMessage("token错误,请重新获取重置密码的token");
        }
        return ServerResponse.createByErrorMessage("修改密码失败");
    }

    //登录状态下:重设密码(controller层从session中获取的user信息进行传入)
    public ServerResponse<String> resetPassword(User user, String passwordOld, String passwordNew){
        //防止这个用户横向越权,要校验这个用户的旧密码,一定是指定这个用户,因为我们会查询一个count(1),如果不指定id,查询出来的count(1)一定>0
        //密码一定要传MD5密码,而不是明文密码
        int resultCount = userMapper.checkPassword(MD5Util.MD5EncodeUtf8(passwordOld),user.getId());
        if (resultCount == 0){
            return ServerResponse.createByErrorMessage("旧密码错误"); //指定用户id的password没有count(1)符合
        }

        //设置密码并更新(更新时返回生效的记录)
        user.setPassword(MD5Util.MD5EncodeUtf8(passwordNew));
        int updateCount = userMapper.updateByPrimaryKeySelective(user);
        if (updateCount > 0){
            return ServerResponse.createBySuccessMessages("密码更新成功");
        }
        return ServerResponse.createByErrorMessage("密码更新失败");
    }

    //登录状态下:更新个人信息
    public ServerResponse<User> updateInformation(User user){
        //username不能被更新,传参是新的user信息
        //校验新的email是否已存在且不是该userId对应的email(因为在未修改该email之前,这个usrId对应的email肯定是存在的)
        int resultCount = userMapper.checkEmailByUserId(user.getEmail(),user.getId());
        if (resultCount > 0){
             //除了传参的新userId对应的email已经存在外,还有该email已经存在
            return ServerResponse.createByErrorMessage("email已存在,请更换email再尝试更新");
        }

        //当逻辑进行到这步可以进行更新
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setEmail(user.getEmail());
        updateUser.setPhone(user.getPhone());
        updateUser.setQuestion(user.getQuestion());
        updateUser.setAnswer(user.getAnswer());

        int updateCount = userMapper.updateByPrimaryKeySelective(updateUser);
        if (updateCount > 0){
            return ServerResponse.createBySuccess("更新个人信息成功!",updateUser);
        }
        return ServerResponse.createByErrorMessage("更新个人信息失败!");
    }

    //获取登录用的信息
    public ServerResponse<User> getInformation(Integer userId){
        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null){
            return ServerResponse.createByErrorMessage("找不到当前用户");
        }

        //找到当前用户后将密码置空
        user.setPassword(StringUtils.EMPTY);
        return ServerResponse.createBySuccess(user);
    }
}
